package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.commerce.common.core.entity.MessageObject;
import top.lixunda.common.kdniao.api.ApiKdniaoTrackQuery;
import top.lixunda.common.kdniao.api.ApiOrderDistinguish;
import top.lixunda.common.kdniao.entity.OrderDistinguishResultDTO;
import top.lixunda.common.kdniao.entity.Shippers;
import top.lixunda.common.kdniao.entity.Traces;
import top.lixunda.common.kdniao.entity.TrackQueryResultDTO;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheStore;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheUser;
import top.lixunda.ecommerce.server.good.api.entity.db.GoodOrderDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.DeliverGoodChangeDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.DeliverGoodDTO;
import top.lixunda.ecommerce.server.good.api.entity.vo.OrderDistinguishVO;
import top.lixunda.ecommerce.server.good.api.entity.vo.OrderTranceVO;
import top.lixunda.ecommerce.server.good.api.entity.vo.TranceVO;
import top.lixunda.ecommerce.server.good.mapper.GoodOrderMapper;
import top.lixunda.ecommerce.server.good.service.IGoodDeliverService;
import top.lixunda.ecommerce.server.user.api.entity.db.StoreAddressDO;
import top.lixunda.ecommerce.server.user.api.feign.IFeignStoreAddressController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author lixunda
 * @version time:2020/3/5 15:38
 */
@Slf4j
@Service
public class GoodDeliverServiceImpl extends BaseServiceImpl<GoodOrderMapper, GoodOrderDO>
        implements IGoodDeliverService {

    private final GoodOrderMapper goodOrderMapper;

    private final IFeignStoreAddressController storeAddressController;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    public GoodDeliverServiceImpl(GoodOrderMapper goodOrderMapper,
                                  IFeignStoreAddressController storeAddressController) {
        this.goodOrderMapper = goodOrderMapper;
        this.storeAddressController = storeAddressController;
    }

    /**
     * 对某个订单进行发货
     *
     * @param deliverGoodDTO 发货相关信息，包括物流信息
     * @return 返回订单发货后的订单基本信息
     */
    @Override
    public GoodOrderDO deliverGoodByOrderId(DeliverGoodDTO deliverGoodDTO) {
        // 调用更改发货信息发货
        DeliverGoodChangeDTO deliverGoodChangeDTO = new DeliverGoodChangeDTO();
        deliverGoodChangeDTO.setOrderId(deliverGoodDTO.getOrderId())
                .setAddressId(deliverGoodDTO.getAddressId())
                .setLogisticsCode(deliverGoodDTO.getLogisticsCode())
                .setLogisticsNumber(deliverGoodDTO.getLogisticsNumber())
                .setLogisticsName(deliverGoodDTO.getLogisticsName());
        return changeDeliverGoodByOrderId(deliverGoodChangeDTO);
    }

    /**
     * 对某个订单进行发货
     *
     * @param deliverGoodList 发货相关信息，包括物流信息
     * @return 返回订单发货后的订单基本信息
     */
    @Override
    public List<GoodOrderDO> deliverGoodByOrderIds(List<DeliverGoodDTO> deliverGoodList) {
        if (ObjectValidators.isEmpty(deliverGoodList)) {
            throw getAppException("参数不能为空");
        }
        List<GoodOrderDO> list = new ArrayList<>(deliverGoodList.size());
        // 批量发货循环调用单个发货
        for (DeliverGoodDTO deliverGoodDTO : deliverGoodList) {
            list.add(deliverGoodByOrderId(deliverGoodDTO));
        }
        return list;
    }

    /**
     * 修改发货后的订单发货信息
     *
     * @param deliverGoodChangeDTO 发货相关信息，包括物流信息
     * @return 返回订单发货后的订单基本信息
     */
    @Override
    public GoodOrderDO changeDeliverGoodByOrderId(DeliverGoodChangeDTO deliverGoodChangeDTO) {
        if (ObjectValidators.isEmpty(deliverGoodChangeDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheStore cacheStore = currentStoreCacheNotNull();
        // 查询订单信息
        GoodOrderDO goodOrderDO = goodOrderMapper.selectById(deliverGoodChangeDTO.getOrderId());
        if (ObjectValidators.isEmpty(goodOrderDO)) {
            throw getAppException("订单不存在");
        }
        if (!cacheStore.getId().equals(goodOrderDO.getStoreId())) {
            throw getAppException("权限不足");
        }
        // 查询物流信息
        MessageObject<StoreAddressDO> storeAddressMessage =
                storeAddressController.queryAddressById(deliverGoodChangeDTO.getAddressId());
        if (ObjectValidators.isEmpty(storeAddressMessage) ||
                ObjectValidators.isEmpty(storeAddressMessage.getObject())) {
            throw getAppException("发货地址不存在");
        }
        if (!goodOrderDO.getState().equals(GoodOrderDO.STATE_TO_TRANSPORTING) &&
                !goodOrderDO.getState().equals(GoodOrderDO.STATE_TO_TRANS)) {
            throw getAppException("该订单无法添加或修改发货信息");
        }
        StoreAddressDO storeAddressDO = storeAddressMessage.getObject();
        goodOrderDO.setStartAddressId(storeAddressDO.getId())
                .setStartAddressDesc(storeAddressDO.toString())
                .setLogisticsNumber(deliverGoodChangeDTO.getLogisticsNumber())
                .setLogisticsCode(deliverGoodChangeDTO.getLogisticsCode())
                .setLogisticsType(deliverGoodChangeDTO.getLogisticsName())
                .setGoodTime(LocalDateTime.now())
                .setState(GoodOrderDO.STATE_TO_TRANSPORTING);
        boolean success = goodOrderDO.updateById();
        if (!success) {
            log.error("更新订单信息发货失败");
            throw getAppException("更新订单信息失败");
        }
        return goodOrderMapper.selectById(goodOrderDO.getId());
    }

    /**
     * 根据订单id取消发货信息
     *
     * @param orderIds 订单id
     * @return 是否取消成功
     */
    @Override
    public boolean cancelDeliverByOrderIds(List<Integer> orderIds) {
        if (ObjectValidators.isEmpty(orderIds)) {
            throw getAppException("订单id不能为空");
        }
        CacheStore cacheStore = currentStoreCacheNotNull();
        this.update(new LambdaUpdateWrapper<GoodOrderDO>()
                .in(GoodOrderDO::getId, orderIds)
                .eq(GoodOrderDO::getStoreId, cacheStore.getId())
                .set(GoodOrderDO::getState, GoodOrderDO.STATE_TO_TRANS));
        return true;
    }

    /**
     * 修改发货后的订单发货信息
     *
     * @param deliverGoodChangeList 发货相关信息，包括物流信息
     * @return 返回订单发货后的订单基本信息
     */
    @Override
    public List<GoodOrderDO> changeDeliverGoodByOrderIds(List<DeliverGoodChangeDTO> deliverGoodChangeList) {
        if (ObjectValidators.isEmpty(deliverGoodChangeList)) {
            throw getAppException("参数不能为空");
        }
        List<GoodOrderDO> list = new ArrayList<>(deliverGoodChangeList.size());
        for (DeliverGoodChangeDTO deliverGoodChangeDTO : deliverGoodChangeList) {
            list.add(changeDeliverGoodByOrderId(deliverGoodChangeDTO));
        }
        return list;
    }

    /**
     * 物流订单号识别
     *
     * @param code 物流订单号
     * @return 识别信息，可能多个
     */
    @Override
    public List<OrderDistinguishVO> orderDistinguish(String code) {
        if (ObjectValidators.isEmpty(code)) {
            throw getAppException("物流订单号不能为空");
        }
        OrderDistinguishResultDTO resultDTO = null;
        try {
            resultDTO = ApiOrderDistinguish.getOrderTracesByJson(code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (resultDTO == null || !resultDTO.getSuccess()) {
            return Collections.emptyList();
        }
        OrderDistinguishVO orderDistinguishVO;
        List<OrderDistinguishVO> resultList = new ArrayList<>(resultDTO.getShippers().size());
        for (Shippers shippers : resultDTO.getShippers()) {
            orderDistinguishVO = new OrderDistinguishVO();
            orderDistinguishVO.setKey(shippers.getShipperCode());
            orderDistinguishVO.setValue(shippers.getShipperName());
            resultList.add(orderDistinguishVO);
        }
        return resultList;
    }

    /**
     * 店铺权限
     */
    private static final String STORE = "STORE";

    /**
     * 普通用户权限
     */
    private static final String USER = "USER";

    /**
     * 根据订单号查询物流信息
     *
     * @param orderId  订单编号
     * @param userType 用户类型，判别权限
     * @return 物流信息
     */
    @SuppressWarnings("AlibabaUndefineMagicConstant")
    private OrderTranceVO queryTranceByOrderId(Integer orderId, String userType) {
        if (ObjectValidators.isEmpty(orderId)) {
            throw getAppException("订单号不能为空");
        }
        GoodOrderDO goodOrderDO = goodOrderMapper.selectById(orderId);
        if (ObjectValidators.isEmpty(goodOrderDO)) {
            throw getAppException("订单不存在");
        }
        // 权限鉴别
        if (STORE.equals(userType)) {
            CacheStore cacheStore = currentStoreCacheNotNull();
            if (!cacheStore.getId().equals(goodOrderDO.getStoreId())) {
                throw getAppException("订单权限不足");
            }
        } else if (USER.equals(userType)) {
            CacheUser userInfoDO = currentUserCacheNotNull();
            if (!userInfoDO.getAccount().equals(goodOrderDO.getUserId())) {
                throw getAppException("订单权限不足");
            }
        }
        if (ObjectValidators.isEmpty(goodOrderDO.getLogisticsNumber()) ||
                ObjectValidators.isEmpty(goodOrderDO.getLogisticsCode())) {
            throw getAppException("没有找到该订单的物流信息");
        }
        TrackQueryResultDTO trackQueryResultDTO = null;
        try {
            trackQueryResultDTO = ApiKdniaoTrackQuery.getOrderTracesByJson(goodOrderDO.getLogisticsCode(), goodOrderDO.getLogisticsNumber());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (ObjectValidators.isEmpty(trackQueryResultDTO)) {
            throw getAppException("查询物流信息失败");
        }
        OrderTranceVO orderTranceVO = new OrderTranceVO();
        List<TranceVO> traces = new ArrayList<>();
        TranceVO vo;
        if (ObjectValidators.isNotEmpty(trackQueryResultDTO.getTraces())) {
            for (Traces t : trackQueryResultDTO.getTraces()) {
                vo = new TranceVO();
                vo.setTime(t.getAcceptTime())
                        .setDesc(t.getAcceptStation())
                        .setRemark(t.getRemark());
                traces.add(vo);
            }
        }
        orderTranceVO.setOrderId(String.valueOf(goodOrderDO.getId()))
                .setShipperCode(goodOrderDO.getLogisticsCode())
                .setShipperName(goodOrderDO.getLogisticsType())
                .setLogisticNumber(goodOrderDO.getLogisticsNumber())
                .setState(trackQueryResultDTO.getState())
                .setTraces(traces);
        return orderTranceVO;
    }

    /**
     * 商铺用户调用，根据订单号查询物流信息
     *
     * @param orderId 订单id
     * @return 物流信息
     */
    @Override
    public OrderTranceVO queryTranceByOrderIdStore(Integer orderId) {
        return queryTranceByOrderId(orderId, STORE);
    }

    /**
     * 管理员用户调用，根据订单号查询物流信息
     *
     * @param orderId 订单id
     * @return 物流信息
     */
    @Override
    public OrderTranceVO queryTranceByOrderIdAdmin(Integer orderId) {
        return queryTranceByOrderId(orderId, "");
    }

    /**
     * 用户调用，根据订单号查询物流信息
     *
     * @param orderId 订单id
     * @return 物流信息
     */
    @Override
    public OrderTranceVO queryTranceByOrderIdUser(Integer orderId) {
        return queryTranceByOrderId(orderId, USER);
    }

    /**
     * 用户调用，根据订单号收货
     *
     * @param orderId 订单id
     * @return 收货是否成功
     */
    @Override
    public Boolean takeDeliveryByOrderId(Integer orderId) {
        if (ObjectValidators.isEmpty(orderId)) {
            throw getAppException("订单id不能为空");
        }
        CacheUser userInfoDO = currentUserCacheNotNull();
        GoodOrderDO goodOrderDO = new GoodOrderDO();
        goodOrderDO.setId(orderId)
                .setState(GoodOrderDO.STATE_END)
                .setEndTime(LocalDateTime.now());
        goodOrderMapper.update(goodOrderDO, new LambdaUpdateWrapper<GoodOrderDO>()
                .eq(GoodOrderDO::getId, orderId)
                .eq(GoodOrderDO::getUserId, userInfoDO.getAccount())
                .and(wrapper -> wrapper.or().eq(GoodOrderDO::getState, GoodOrderDO.STATE_RECEIVED)
                        .or().eq(GoodOrderDO::getState, GoodOrderDO.STATE_TO_RECEIVE)
                        .or().eq(GoodOrderDO::getState, GoodOrderDO.STATE_TO_TRANSPORTING)));
        return true;
    }

    /**
     * 用户调用，根据订单号收货
     *
     * @param orderIds 订单id
     * @return 收货是否成功
     */
    @Override
    public Boolean takeDeliveryByOrderIds(List<Integer> orderIds) {
        if (ObjectValidators.isEmpty(orderIds)) {
            throw getAppException("订单id不能为空");
        }
        for (Integer id : orderIds) {
            takeDeliveryByOrderId(id);
        }
        return true;
    }
}
